﻿/*******************************************************************
 *     JameE
 *******************************************************************
  Copyright 2010 Clifford Champion and JameE contributors.
  
  This file is part of JameE.
  
  JameE is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  JameE is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with JameE.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************/

/// <reference path="~/Base/Classer.js" />
/// <reference path="~/Base/IncludeLoader.js" />

$include(
[
	"Engine/Message.js"
]);

$class(
"JameE.Engine.PostOffice",
{
	/////////////////////
	// CONSTANT
	/////////////
	MESSAGE_TYPE_ALL: -1,


	/////////////////////
	// FIELDS
	/////////////
	_oMessageListeners: null,


	/////////////////////
	// CONSTRUCTOR
	/////////////
	_ctor: function (args) {
		this._oMessageListeners = {};
		this._oMessageListeners[this.MESSAGE_TYPE_ALL] = [];
	},


	/////////////////////
	// METHODS
	/////////////
	attachMessageListener: function (arr_iMessageTypes, fnListener) {
		$require_type(fnListener, "function");

		if (arr_iMessageTypes === null) {
			arr_iMessageTypes = [this.MESSAGE_TYPE_ALL];
		}
		else if ($typeof(arr_iMessageTypes) === "number") {
			arr_iMessageTypes = [arr_iMessageTypes];
		}
		else {
			$require_type_null(arr_iMessageTypes, "array");
		}

		var oListeners = this._oMessageListeners;

		var iNumMessageTypes = arr_iMessageTypes.length;
		for (var i = 0; i < iNumMessageTypes; ++i) {
			var iMessageType = arr_iMessageTypes[i];

			var arr_fnListeners = null;
			if (!oListeners.hasOwnProperty(iMessageType)) {
				arr_fnListeners = [];
				oListeners[iMessageType] = arr_fnListeners;
			}
			else {
				arr_fnListeners = oListeners[iMessageType];
			}

			arr_fnListeners.push(fnListener);
		}
	},

	message: function (oMessage) {
		/// <summary>Processes an incoming message.</summary>
		var oTo = oMessage.getTo();


		//////
		// fire "all" listeners
		var arr_fnListeners = this._oMessageListeners[this.MESSAGE_TYPE_ALL];
		var iNumObjects = arr_fnListeners.length;
		var i;
		for (i = 0; i < iNumObjects; ++i) {
			var fnListener = arr_fnListeners[i];
			fnListener(oMessage);
		}

		//////
		// fire specific listeners
		var iMsg = oMessage.getMessage();
		arr_fnListeners = this._oMessageListeners[iMsg] || null;
		if (arr_fnListeners !== null) {
			iNumObjects = arr_fnListeners.length;
			for (i = 0; i < iNumObjects; ++i) {
				var fnListener = arr_fnListeners[i];
				fnListener(oMessage);
			}
		}

		//////
		// send to object its addressed to.
		if (oTo !== null) {
			oTo.message(oMessage);
		}
	}


	//	/// checks for messages that need to go out, according to their send time.
	//	processOutgoing: function(iCurrentTimeMs) {
	//		var iNum = this._arr_oMessages.length;

	//		for (var i = 0; i < iNum; ++i) {
	//			var oMessage = this._arr_oMessages[i];
	//			if (oMessage == null) {
	//				continue;
	//			}
	//			if (oMessage.iWhenToSendMs < iCurrentTimeMs) {
	//				oMessage.oTo.message(oMessage);
	//			}
	//			this._arr_oMessages[i] = null;
	//		}
	//	},

	//	sendMessage: function(oMessage, iDelayMs) {
	//		if (oMessage.oTo == null) {
	//			return;
	//		}

	//		if (typeof (iDelayMs) !== "number") {
	//			iDelayMs = 1;
	//		}
	//		else if (iDelayMs < 0) {
	//			iDelayMs = 0;
	//		}

	//		//////
	//		// message is instant, send it.
	//		if (iDelayMs === 0) {
	//			oMessage.oTo.message(oMessage);
	//			return;
	//		}

	//		//////
	//		// message is to be delayed.

	//		var oDelayedMessage = {
	//			oMessage: oMessage,
	//			iWhenToSendMs: iWhen
	//		};

	//		var iNowMs = this._oEngine.getTime();
	//		var iWhen = iNowMs + iDelayMs;

	//		// locate a free element
	//		var bStored = false;
	//		for (var i = 0; i < this._arr_oMessages.length; ++i) {
	//			if (this._arr_oMessages[i] == null) {
	//				this._arr_oMessages[i] = oDelayedMessage;
	//				bStored = true;
	//				break;
	//			}
	//		}
	//		if (!bStored) {
	//			this._arr_oMessages.push(oDelayedMessage);
	//		}
	//	}
});

$include_notify("Engine/PostOffice.js");
